using DA.AnimGraph;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

namespace DA.AnimGraph.Editor {

    public class AGEContext {

        private bool isDirty => handleManager.dirty;
        public AUID uuid => assetHandle.uuid;
        internal readonly AGAAssetHandle assetHandle;

        internal readonly ResourceManager resourceManager;
        internal readonly TimelineManager timelineManager;
        internal readonly PreviewManager previewManager;
        private readonly HandleManager handleManager;
        private readonly CommandManager commandManager;

        internal ServiceManager serviceManager => ageEnv.serviceManager;
        internal readonly AGEEnvironment ageEnv;
        internal readonly AnimGraphEditorWindow window;

        public readonly string titleText;

        const float updateStep = 1f;
        float updateTimer = 0;

        internal AGEContext(string path, AGEEnvironment ageEnv) {
            assetHandle = AGAAssetHandle.Open(path);

            var fileName = Path.GetFileNameWithoutExtension(path);
            titleText = fileName; // $"{window.titleContent} ({fileName})";

            if (ageEnv != null) {
                this.ageEnv = ageEnv;
                window = ageEnv.window;
                window.SetTitle(titleText);
            }

            handleManager = new HandleManager();
            commandManager = new CommandManager();
            previewManager = new PreviewManager(this);
            resourceManager = new ResourceManager(assetHandle.GetResources());
            timelineManager = new TimelineManager(assetHandle.GetTimeline());

            handleManager.OnDirtyChange += OnDirtyChange;
        }

        internal AGAHandle_Root GetRootHandle() {
            var handle = assetHandle.GetRootHandle(handleManager, commandManager);
            return handle;
        }

        internal void SetMode(AGEMode newMode) {
            ageEnv?.SetMode(newMode);
        }

        #region Save & Export

        public bool Save() {
            try {
                var resources = resourceManager.Dump();
                assetHandle.SetResources(resources);
                var timeline = timelineManager.Dump();
                assetHandle.SetTimeline(timeline);
                assetHandle.Save();
                D.L($"保存成功 {titleText}");

                handleManager.OnSave();

                return true;
            }
            catch (System.Exception e) {
                D.Exception($"保存报错 {titleText}\n{e}\n");
                return false;
            }
        }
        public bool SaveIfDirty() {
            if (isDirty) {
                return Save();
            }
            return true;
        }

        private void Publish() {
            if (SaveIfDirty()) {
                try {
                    var timelines = timelineManager.Publish();
                    assetHandle.Publish(timelines);
                    D.L($"导出成功 {titleText}");
                }
                catch (System.Exception e) {
                    D.Exception($"导出报错 {titleText}\n{e}\n");
                }
            }
        }

        /// 导出使用这个版本
        public void ExportDry() {
            if (SaveIfDirty()) {
                try {
                    var timelines = timelineManager.Publish();
                    assetHandle.ExportDry(timelines);
                    D.L($"导出Dry成功 {titleText}");
                }
                catch (System.Exception e) {
                    D.Exception($"导出Dry报错 {titleText}\n{e}\n");
                }
            }
        }

        // 预览用
        public AnimGraphPublishAsset ExportAgpAsset() {
            if (SaveIfDirty()) {
                var timelines = timelineManager.Publish();
                var agp = assetHandle.ExportToAGPAsset(timelines);
                return agp;
            }
            return null;
        }

        /// <summary>
        /// 批量导出时使用，区别是不进行保存，跳过没设置导出路径的文件
        /// </summary>
        public bool BatchExport() {
            if (string.IsNullOrEmpty(assetHandle.publishPath)) {
                D.L($"[批量导出] 未设置导出路径跳过文件： {titleText}");
                return false;
            }
            try {
                var timelines = timelineManager.Publish();
                assetHandle.ExportDry(timelines);
                D.L($"批量导出成功 {titleText}");
            }
            catch (Exception e) {
                D.Exception($"批量导出报错 {titleText}\n{e}\n");
                return false;
            }
            return true;
        }

        private void OnDirtyChange(bool dirty) {
            if (dirty) {
                window?.SetTitle(titleText + "*");
            } else {
                window?.SetTitle(titleText);
            }
        }

        #endregion

        internal List<AGA_Blackboard.Entry> GetBlackboardEntriesInType(AGABlackboardType type) {
            var rootDataHandle = GetRootHandle();
            return rootDataHandle.GetBlackboardEntriesInType(type);
        }
        public Dictionary<string, AGABlackboardType> GetBlackboardInfo() {
            var rootDataHandle = GetRootHandle();
            return rootDataHandle.GetBlackboardInfo();
        }

        internal void OnDisable() {
            previewManager.OnDisable();
            if (handleManager.dirty) {
                var needSave = EditorUtility.DisplayDialog("save", "anim graph editor 即将关闭\n需要在关闭前保存吗？", "yes", "no");
                if (needSave) {
                    Save();
                }
            }
        }
        public void Update() {
            updateTimer -= Time.deltaTime;

            if (updateTimer <= 0) {

                updateTimer = updateStep;
            }
        }
    }


    internal class CommandManager {

    }


}